package me.ezitku.base.ScreenRecord.service

import android.app.Service
import android.content.Context
import android.content.Intent
import android.hardware.display.DisplayManager
import android.hardware.display.VirtualDisplay
import android.media.MediaRecorder
import android.media.projection.MediaProjection
import android.media.projection.MediaProjectionManager
import android.os.Build
import android.os.Environment
import android.os.IBinder
import android.util.Log
import com.ug_project.system.defaultPattern
import com.ug_project.system.nowTimeString
import me.ezitku.base.ScreenRecord.createMediaProjection
import me.ezitku.base.extensions.baseAppPath
import java.io.FileDescriptor

import java.io.IOException
import java.sql.Date
import java.text.SimpleDateFormat

class ScreenRecordService : Service() {

    private var mScreenWidth: Int = 0
    private var mScreenHeight: Int = 0
    private var mScreenDensity: Int = 0
    private var mResultCode: Int = 0
    private var mResultData: Intent? = null
    /**
     * 是否为标清视频
     */
    private var isVideoSd: Boolean = false
    /**
     * 是否开启音频录制
     */
    private var isAudio: Boolean = false

    /**
     * ساقلايدىغان ئادرىسى
     */
    private var filePath = baseAppPath + nowTimeString("yyyy-MM-dd-HH-mm-ss") + ".nur"

    private var mMediaProjection: MediaProjection? = null
    private var mMediaRecorder: MediaRecorder? = null
    private var mVirtualDisplay: VirtualDisplay? = null

    override fun onCreate() {
        super.onCreate()
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        mResultCode = intent.getIntExtra("code", -1)
        mResultData = intent.getParcelableExtra<Intent>("data")
        mScreenWidth = intent.getIntExtra("width", 720)
        mScreenHeight = intent.getIntExtra("height", 1280)
        mScreenDensity = intent.getIntExtra("density", 1)
        isVideoSd = intent.getBooleanExtra("quality", true)
        isAudio = intent.getBooleanExtra("audio", false)
        filePath = intent.getStringExtra("filePath")

        mMediaProjection = createMediaProjection(mResultCode, mResultData!!)
        mMediaRecorder = createMediaRecorder()
        mVirtualDisplay = createVirtualDisplay() // 必须在mediaRecorder.prepare() 之后调用，否则报错"fail to get surface"
        mMediaRecorder!!.start()

        Log.i(TAG, filePath)

        return Service.START_NOT_STICKY
    }

    private fun createMediaProjection(): MediaProjection? {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            return (getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager).getMediaProjection(mResultCode, mResultData!!)
        }
        return null
    }

    private fun createMediaRecorder(): MediaRecorder {
        val formatter = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss")
        val curDate = Date(System.currentTimeMillis())
        val curTime = formatter.format(curDate).replace(" ", "")
        var videoQuality = "HD"
        if (isVideoSd) videoQuality = "SD"

        Log.i(TAG, "Create MediaRecorder")
        val mediaRecorder = MediaRecorder()
        if (isAudio) mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC)
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE)
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
        mediaRecorder.setOutputFile(filePath)
        mediaRecorder.setVideoSize(mScreenWidth, mScreenHeight)  //after setVideoSource(), setOutFormat()
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264)  //after setOutputFormat()
        if (isAudio)
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)  //after setOutputFormat()
        val bitRate: Int

        if (isVideoSd) {
            /**
             * ئېنىقلىقى نورمال
             */
            mediaRecorder.setVideoEncodingBitRate(mScreenWidth * mScreenHeight)
            mediaRecorder.setVideoFrameRate(30)
            bitRate = mScreenWidth * mScreenHeight / 1000
        } else {
            /**
             * ئېنىقلىقى يۇقىرى
             */
            mediaRecorder.setVideoEncodingBitRate(5 * mScreenWidth * mScreenHeight)
            mediaRecorder.setVideoFrameRate(60) //after setVideoSource(), setOutFormat()
            bitRate = 5 * mScreenWidth * mScreenHeight / 1000
        }
        try {
            mediaRecorder.prepare()
        } catch (e: IllegalStateException) {
            // TODO Auto-generated catch block
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        }
        mediaRecorder.setOutputFile(FileDescriptor())
        return mediaRecorder
    }

    private fun createVirtualDisplay(): VirtualDisplay? {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            return mMediaProjection!!.createVirtualDisplay(TAG, mScreenWidth, mScreenHeight, mScreenDensity,
                    DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mMediaRecorder!!.surface, null, null)
        }
        return null
    }

    override fun onDestroy() {
        super.onDestroy()
        if (mVirtualDisplay != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                mVirtualDisplay!!.release()
            }
            mVirtualDisplay = null
        }
        if (mMediaRecorder != null) {
            mMediaRecorder!!.setOnErrorListener(null)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                mMediaProjection!!.stop()
            }
            mMediaRecorder!!.reset()
        }
        if (mMediaProjection != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                mMediaProjection!!.stop()
            }
            mMediaProjection = null
        }
    }

    override fun onBind(intent: Intent): IBinder? {
        // TODO Auto-generated method stub
        return null
    }

    companion object {

        private val TAG = "ScreenRecordingService"
    }

}
